package com.youlu.campus.service.form.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityUserRecord;
import com.youlu.campus.entity.FileExportTask;
import com.youlu.campus.entity.SystemOptLog;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserInfoExtend;
import com.youlu.campus.entity.VO.req.UserFormTaskInfoQueryVO;
import com.youlu.campus.entity.form.FormTaskConfig;
import com.youlu.campus.entity.form.SingleFormAnswer;
import com.youlu.campus.entity.form.SingleFormQuestion;
import com.youlu.campus.entity.form.UserFormTaskDetailInfo;
import com.youlu.campus.entity.form.UserFormTaskInfo;
import com.youlu.campus.entity.form.domain.UserSubmitSingleForm;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.file.FileExportTaskService;
import com.youlu.campus.service.file.FileService;
import com.youlu.campus.service.form.FormTaskConfigService;
import com.youlu.campus.service.form.SingleFormAnswerService;
import com.youlu.campus.service.form.SingleFormQuestionService;
import com.youlu.campus.service.form.UserFormTaskInfoService;
import com.youlu.campus.service.system.SystemOptLogService;
import com.youlu.campus.service.university.UniversityInfoService;
import com.youlu.campus.service.visitor.UserInfoExtendService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UserFormTaskInfoServiceImpl implements UserFormTaskInfoService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Lazy
    @Autowired
    private UserInfoExtendService userInfoExtendService;
    @Autowired
    private FileExportTaskService fileExportTaskService;
    @Autowired
    private SystemOptLogService systemOptLogService;
    @Lazy
    @Autowired
    private FormTaskConfigService formTaskConfigService;
    @Autowired
    private FileService fileService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private UniversityInfoService universityInfoService;
    @Lazy
    @Autowired
    private SingleFormQuestionService singleFormQuestionService;
    @Lazy
    @Autowired
    private SingleFormAnswerService singleFormAnswerService;
    /**
     * Admin 后台文件导出地址
     */
    @Value("${sys.fileExportPath:/data/file/campus-admin/}")
    private String fileExportPath;
    HashMap<String, UniversityInfo> universityCache = new HashMap<>();
    HashMap<String, ActivityInfo> activityCache = new HashMap<>();
    HashMap<String, SingleFormQuestion> questionCache = new HashMap<>();
    HashMap<String, SingleFormAnswer> answerCache = new HashMap<>();
    HashMap<String, List<SingleFormAnswer>> answersCache = new HashMap<>();

    @Override
    public Page<UserFormTaskInfo> list(UserFormTaskInfoQueryVO req) {
        log.info(":>>> 开始获取用户表单列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取获取用户表单列表参数错误:参数为空");
            throw new BusinessException("获取用户表单列表参数错误");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getFormId())) {
            query.addCriteria(Criteria.where("formTaskConfigId").is(req.getFormId()));
        }
        if (StringUtils.isNotBlank(req.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
        }
        if (StringUtils.isNotBlank(req.getName())) {
            query.addCriteria(Criteria.where("name").is(req.getName()));
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, UserFormTaskInfo.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserFormTaskInfo> infos = mongoTemplate.find(query.with(pageRequest), UserFormTaskInfo.class);
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    @Override
    public boolean create(UserFormTaskInfo req) {
        log.info(":>>> 开始创建用户表单数据:{}", JSON.toJSON(req));
        boolean exist = existWith(req.getUserId(), req.getFormTaskConfigId());
        if (exist) {
            log.error(":>>> 表单已经存在，请不要重复提交");
            throw new BusinessException("表单已经存在，请不要重复提交");
        }
        List<UserFormTaskDetailInfo> datas = new ArrayList<>();
        for (UserFormTaskDetailInfo u : req.getItems()) {
            UserFormTaskDetailInfo copy = new UserFormTaskDetailInfo();
            BeanUtils.copyProperties(u, copy);
            datas.add(copy);
        }
        UserInfoExtend extend = userInfoExtendService.findByUserId(req.getUserId());
        if (Objects.nonNull(extend)) {
            req.setName(extend.getName());
            req.setUniversityId(extend.getUniversityId());
            req.setUniversityName(extend.getUniversityName());
            req.setMobile(extend.getMobile());
        }
        Date date = new Date();
        req.setId(null);
        req.setCreatedTime(date);
        req.setStatus("done");
        req = mongoTemplate.insert(req);
        /**
         * 类型，
         * single-choice:单选题
         * multiple-choice:多项选择题
         * text-box:文本框
         * file-upload:文件上传
         * image-upload:图片上传
         * video-upload:视频上传
         * number-box:数字输入框
         * date-box:数字输入框
         */
        for (UserFormTaskDetailInfo u : datas) {
            switch (u.getType()) {
                case "single-choice":
                    break;
                case "multiple-choice":
                    break;
                case "text-box":
                    break;
                case "file-upload":
                    break;
                case "image-upload":
                    break;
                case "video-upload":
                    break;
                case "number-box":
                    break;
                case "date-box":
                    break;
                default:
                    break;
            }
            u.setCreatedTime(date);
            u.setId(null);
            u.setUserFormTaskInfoId(req.getId());
            mongoTemplate.insert(u);
        }
        return true;
    }

    @Override
    public boolean update(UserFormTaskInfo req) {
        log.info(":>>> 开始修改用户表单数据:{}", JSON.toJSON(req));
        UserFormTaskInfo exist = this.findOne(req.getId());
        if (Objects.isNull(exist)) {
            log.error(":>>> 表单不存在");
            throw new BusinessException("表单不存在");
        }
        Date date = new Date();
        Update update = new Update();
        if (StringUtils.isNotBlank(req.getStatus())) {
            update.set("status", req.getStatus());
        } else {
            update.set("status", "done");
        }
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateFirst(new Query().addCriteria(Criteria.where("id").is(req.getId())), update, UserFormTaskInfo.class);
        if (!(updateResult.getModifiedCount() > 0)) {
            return false;
        }
        List<UserFormTaskDetailInfo> datas = new ArrayList<>();
        for (UserFormTaskDetailInfo u : req.getItems()) {
            UserFormTaskDetailInfo copy = new UserFormTaskDetailInfo();
            BeanUtils.copyProperties(u, copy);
            datas.add(copy);
        }
        /**
         * 类型，
         * single-choice:单选题
         * multiple-choice:多项选择题
         * text-box:文本框
         * file-upload:文件上传
         * image-upload:图片上传
         * video-upload:视频上传
         * number-box:数字输入框
         * date-box:数字输入框
         */
        Query removeQ = new Query();
        removeQ.addCriteria(Criteria.where("userFormTaskInfoId").is(req.getId()));
        mongoTemplate.remove(removeQ, UserFormTaskDetailInfo.class);
        for (UserFormTaskDetailInfo u : datas) {
            switch (u.getType()) {
                case "single-choice":
                    break;
                case "multiple-choice":
                    break;
                case "text-box":
                    break;
                case "file-upload":
                    break;
                case "image-upload":
                    break;
                case "video-upload":
                    break;
                case "number-box":
                    break;
                case "date-box":
                    break;
                default:
                    break;
            }
            u.setCreatedTime(date);
            u.setId(null);
            u.setUserFormTaskInfoId(req.getId());
            mongoTemplate.insert(u);
        }
        return true;
    }

    @Override
    public UserFormTaskInfo findBy(String userId, String formId) {
        log.info(":>>> 开始查找用户表单数据:{},{}", userId, formId);
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("formTaskConfigId").is(formId));
        UserFormTaskInfo userFormTaskInfo = mongoTemplate.findOne(query, UserFormTaskInfo.class);
        if (Objects.isNull(userFormTaskInfo)) {
            userFormTaskInfo = new UserFormTaskInfo();
            userFormTaskInfo.setUserId(userId);
            userFormTaskInfo.setFormTaskConfigId(formId);
            userFormTaskInfo.setStatus("todo");
            log.error(":>>> 用户表单数据不存在:状态为 todo {},{}", userId, formId);
            return userFormTaskInfo;
        }
        Query queryDetail = new Query();
        queryDetail.addCriteria(Criteria.where("userFormTaskInfoId").is(userFormTaskInfo.getId()));
        Sort sort = Sort.by(Sort.Direction.ASC, "no");
        queryDetail.with(sort);
        List<UserFormTaskDetailInfo> details = mongoTemplate.find(queryDetail, UserFormTaskDetailInfo.class);
        userFormTaskInfo.setItems(details);
        return userFormTaskInfo;
    }

    @Override
    public UserFormTaskInfo findOne(String id) {
        log.info(":>>> 开始查找用户表单数据:{}", id);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        UserFormTaskInfo userFormTaskInfo = mongoTemplate.findOne(query, UserFormTaskInfo.class);
        if (Objects.isNull(userFormTaskInfo)) {
            return userFormTaskInfo;
        }
        Query queryDetail = new Query();
        queryDetail.addCriteria(Criteria.where("userFormTaskInfoId").is(userFormTaskInfo.getId()));
        Sort sort = Sort.by(Sort.Direction.ASC, "no");
        queryDetail.with(sort);
        List<UserFormTaskDetailInfo> details = mongoTemplate.find(queryDetail, UserFormTaskDetailInfo.class);
        userFormTaskInfo.setItems(details);
        return userFormTaskInfo;
    }

    @Override
    public boolean existWith(String userId, String formTaskConfigId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("formTaskConfigId").is(formTaskConfigId));
        return mongoTemplate.exists(query, UserFormTaskInfo.class);
    }

    @Override
    public boolean export(UserFormTaskInfoQueryVO req) {
        log.info(":>>> 开始用户表单导出:{}", JSON.toJSONString(req));
        if (StringUtils.isBlank(req.getFormId())) {
            log.error(":>>> 导出用户表单表单ID为空,系统拒绝导出");
            return false;
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
        }
        if (StringUtils.isNotBlank(req.getName())) {
            query.addCriteria(Criteria.where("name").is(req.getName()));
        }
        if (StringUtils.isNotBlank(req.getFormId())) {
            query.addCriteria(Criteria.where("formTaskConfigId").is(req.getFormId()));
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        Long count = mongoTemplate.count(query, UserFormTaskInfo.class);
        log.info(":>>> 用户表单需要导出的总数量:{},{}", req.getFormId(), count);
        if (count.compareTo(0L) == -1) {
            log.error(":>>> 用户表单为空");
            return false;
        }
        FileExportTask fileExportTask = new FileExportTask();
        fileExportTask.setToken(req.getOptUserName());
        fileExportTask.setBizType("form");
        fileExportTask.setStatus(0);
        fileExportTask.setOptUser(req.getOptUserName());
        fileExportTask.setOptUserId(req.getUserId());

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(new Date());
        FormTaskConfig form = formTaskConfigService.findOne(req.getFormId());
        String fileName = "用户表单-" + form.getName() + "-" + dateStr;
        String f = fileName + new Date().getTime() + ".xlsx";
        fileExportTask.setFileName(f);
        fileExportTask.setNum(count.intValue());
        fileExportTask.setDesc(form.getName() + "用户表单");
        String re = fileExportTaskService.create(fileExportTask);
        SystemOptLog optlog = new SystemOptLog();
        optlog.setIp(req.getIpAddress());
        optlog.setOptUserName(req.getOptUserName());
        optlog.setOptTime(new Date());
        optlog.setBizType("export-user-form");
        optlog.setOptRealName(req.getOptUserRealName());
        optlog.setSqlDetai(JSON.toJSONString(query, SerializerFeature.IgnoreNonFieldGetter));
        optlog.setDesc("导出用户表单文件名:" + f + ",数据总条数:" + count);
        systemOptLogService.create(optlog);
        this.exportUserForm(req.getFormId(), query, count, f, re);
        return true;
    }

    @Override
    public boolean delete(String id) {
        log.info(":>>> 开始删除用户表单");
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        DeleteResult result = mongoTemplate.remove(query, UserFormTaskInfo.class);
        log.info(":>>> 删除用户表单数据结果:{}", result.getDeletedCount() > 0 ? true : false);
        Query removeQ = new Query();
        removeQ.addCriteria(Criteria.where("userFormTaskInfoId").is(id));
        DeleteResult resultDetail = mongoTemplate.remove(removeQ, UserFormTaskDetailInfo.class);
        log.info(":>>> 删除用户表单数据明细结果:{}", resultDetail.getDeletedCount() > 0 ? true : false);
        return result.getDeletedCount() > 0 ? true : false;
    }

    private void exportUserForm(String formId, Query query, Long count, String f, String exportTaskId) {
        int counter = 0;
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        try {
            int rowNum = 1;
            int sheetNum = 1;
            FormTaskConfig form = formTaskConfigService.findOne(formId);
            if (Objects.isNull(form)) {
                log.error(":>>> 表单不存在:{}", formId);
                return;
            }
            //创建一个Excel表单,参数为sheet的名字
            SXSSFSheet sheet = workbook.createSheet("sheet" + "-" + sheetNum);
            setUserFormExcelTitle(workbook, sheet, form);
            //创建表头
            SXSSFRow row = null;
            Integer pageSize = 1000;
            Integer pages = count.intValue() / pageSize + 1;
            boolean setCellTitle = false;
            for (int page = 0; page < pages; page++) {
                log.info(":>>> 开始处理第:{} 页,总页数:{}", page, pages);
                if (page % 100 == 0) {
                    System.gc();
                    log.info(":>>>> 每10页执行Full GC :<<<<");
                }
                query.limit(pageSize);
                query.skip(page * pageSize);
                List<UserFormTaskInfo> contents = mongoTemplate.find(query, UserFormTaskInfo.class);
                if (Objects.isNull(contents) && CollectionUtils.isEmpty(contents)) {
                    log.error(":>>> 第:{} 页，数据为空", page);
                    continue;
                }
                for (UserFormTaskInfo content : contents) {
                    log.info(":>>> 导出行数:{}", counter);
                    if (counter != 0 && counter % 990000 == 0) {
                        //超过990000就自动创建一个sheet
                        sheetNum++;
                        sheet = workbook.createSheet("sheet-" + sheetNum);
                        setUserFormExcelTitle(workbook, sheet, form);
                        //创建表头
                        //新增数据行，并且设置单元格数据
                        rowNum = 1;
                        sheetNum++;
                        log.info(":>>> 操作600000行,创建新sheet");
                    }
                    row = sheet.createRow(rowNum);
                    FormTaskConfig taskConfig = formTaskConfigService.findOne(content.getFormTaskConfigId());
                    if (Objects.nonNull(taskConfig)
                            && StringUtils.isNotBlank(taskConfig.getActivityId())
                            && StringUtils.isNotBlank(content.getOpenId())) {
                        Query queryF = new Query();
                        queryF.addCriteria(Criteria.where("openId").is(content.getOpenId()));
                        queryF.addCriteria(Criteria.where("activityId").is(taskConfig.getActivityId()));
                        queryF.with(Sort.by(Sort.Direction.DESC, "createdTime"));
                        List<ActivityUserRecord> activityUserRecordList = this.mongoTemplate.find(queryF, ActivityUserRecord.class);
                        if (!CollectionUtils.isEmpty(activityUserRecordList)) {
                            row.createCell(0).setCellValue("" + activityUserRecordList.get(0).getScore());
                        }
                    }

//                    if (StringUtils.isNotBlank(content.getActivityId())) {
//                        ActivityInfo activityInfo = this.getActivityInfo(content.getActivityId());
//                        if (Objects.nonNull(activityInfo)) {
//                            row.createCell(0).setCellValue(activityInfo.getName());
//                        }
//                    }
                    if (StringUtils.isNotBlank(content.getAppId())) {
                        row.createCell(1).setCellValue(content.getAppId());
                    }
                    if (StringUtils.isNotBlank(content.getOpenId())) {
                        row.createCell(2).setCellValue(content.getOpenId());
                    }
                    if (StringUtils.isNotBlank(content.getUniversityId())) {
                        UniversityInfo universityInfo = this.getUniversity(content.getUniversityId());
                        if (Objects.nonNull(universityInfo)) {
                            row.createCell(3).setCellValue(universityInfo.getName());
                        }
                    }
                    if (StringUtils.isNotBlank(content.getMobile())) {
                        row.createCell(4).setCellValue(content.getMobile());
                    } else {
                        if (StringUtils.isNotBlank(content.getUserId())) {
                            UserInfoExtend ex = userInfoExtendService.findByUserId(content.getUserId());
                            if (Objects.nonNull(ex) && StringUtils.isNotBlank(ex.getMobile())) {
                                row.createCell(4).setCellValue(ex.getMobile());
                            }
                        }
                    }
                    if (StringUtils.isNotBlank(content.getStatus())) {
                        row.createCell(5).setCellValue(content.getStatus());
                    }
                    if (StringUtils.isNotBlank(content.getName())) {
                        row.createCell(6).setCellValue(content.getName());
                    }
                    if (StringUtils.isNotBlank(content.getName())) {
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        row.createCell(7).setCellValue(dateFormat.format(content.getCreatedTime()));
                    }
                    Query detailQuery = new Query().addCriteria(Criteria.where("userFormTaskInfoId").is(content.getId()));
                    Sort sort = Sort.by(Sort.Direction.ASC, "no");
                    detailQuery.with(sort);
                    List<UserFormTaskDetailInfo> detailInfos = mongoTemplate.find(detailQuery, UserFormTaskDetailInfo.class);
                    log.info(":>>> 开始处理用户表单:{},子表单数量:{}", content.getId(), detailInfos.size());
                    if (CollectionUtils.isEmpty(detailInfos)) {
                        continue;
                    }
                    Integer cellNumer = 8;
                    // 开始遍历表单
                    for (UserFormTaskDetailInfo u : detailInfos) {
                        if (StringUtils.isBlank(u.getSingleFormQuestionId())) {
                            continue;
                        }
                        SingleFormQuestion q = this.getSingleFormQuestion(u.getSingleFormQuestionId());
                        if (Objects.isNull(q)) {
                            continue;
                        }

                        /**
                         * 类型，
                         * single-choice:单选题
                         * multiple-choice:多项选择题
                         * text-box:文本框
                         * file-upload:文件上传
                         * image-upload:图片上传
                         * video-upload:视频上传
                         * number-box:数字输入框
                         * date-box:数字输入框
                         */
                        if ("single-choice".equals(q.getType())) {
                            cellNumer = this.setChoiceCell(q, row, cellNumer, u);
                        } else if ("multiple-choice".equals(q.getType())) {
                            cellNumer = this.setChoiceCell(q, row, cellNumer, u);
                        } else if ("text-box".equals(q.getType())) {
                            cellNumer = this.setStringValueToCell(u, row, cellNumer, sheet);
                        } else if ("file-upload".equals(q.getType())) {
                            cellNumer = this.setStringValueToCell(u, row, cellNumer, sheet);
                        } else if ("image-upload".equals(q.getType())) {
                            cellNumer = this.setStringValueToCell(u, row, cellNumer, sheet);
                        } else if ("video-upload".equals(q.getType())) {
                            cellNumer = this.setStringValueToCell(u, row, cellNumer, sheet);
                        } else if ("number-box".equals(q.getType())) {
                            //数量
                            row.createCell(cellNumer++).setCellValue(u.getDatas().size());
                            //内容
                            for (UserSubmitSingleForm data : u.getDatas()) {
                                row.createCell(cellNumer++).setCellValue(data.getNumberValue());
                            }
                        } else if ("date-box".equals(q.getType())) {
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            //数量
                            row.createCell(cellNumer++).setCellValue(u.getDatas().size());
                            //内容
                            for (UserSubmitSingleForm data : u.getDatas()) {
                                SXSSFCell cell = row.createCell(cellNumer++);
                                cell.setCellValue(dateFormat.format(data.getDateValue()));
                            }
                        }
                    }
                    counter++;
                    rowNum++;
                }
            }
            //将excel写入到输出流中
            log.info(":>>> flush:{} 行", rowNum);
            OutputStream outputStream = new FileOutputStream(fileExportPath + f);
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            log.info(":>>> 写文件到本地然后读:{}", f);
            File file = new File(fileExportPath + f);
            InputStream in = new FileInputStream(file);
            String url = fileService.uploadFile(in, f);
            Query queryTask = new Query().addCriteria(Criteria.where("id").is(exportTaskId));
            Update update = new Update();
            update.set("url", url);
            update.set("status", 1);
            update.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateFirst(queryTask, update, FileExportTask.class);
            log.info(":>>> 更新任务:{},状态:{}", exportTaskId, updateResult.getModifiedCount() > 0 ? true : false);
            in.close();
            log.info(":>>> 用户表单内容导出,关闭文件流");
        } catch (Exception e) {
            log.error(":>>> 订单内容导出错误:{}", e);
        }
    }

    private static Integer setStringValueToCell(UserFormTaskDetailInfo u, SXSSFRow row, Integer cellNumer, SXSSFSheet sheet) {
        //数量
        row.createCell(cellNumer++).setCellValue(u.getDatas().size());
        //内容
        for (UserSubmitSingleForm data : u.getDatas()) {
            String stringValue = data.getStringValue();
            SXSSFCell cell = row.createCell(cellNumer++);
            cell.setCellValue(stringValue);
        }
        return cellNumer;
    }


    private ActivityInfo getActivityInfo(String activityId) {
        ActivityInfo activityInfo = null;
        if (activityCache.containsKey(activityId)) {
            activityInfo = activityCache.get(activityId);
        } else {
            activityInfo = activityService.findOne(activityId);
            if (Objects.nonNull(activityInfo)) {
                activityCache.put(activityId, activityInfo);
            }
        }
        return activityInfo;
    }

    private UniversityInfo getUniversity(String universityId) {
        UniversityInfo universityInfo = null;
        if (universityCache.containsKey(universityId)) {
            universityInfo = universityCache.get(universityId);
        } else {
            universityInfo = universityInfoService.findOne(universityId);
            if (Objects.nonNull(universityInfo)) {
                universityCache.put(universityId, universityInfo);
            }
        }
        return universityInfo;
    }

    private SingleFormQuestion getSingleFormQuestion(String id) {
        SingleFormQuestion q = null;
        if (questionCache.containsKey(id)) {
            q = questionCache.get(id);
        } else {
            q = singleFormQuestionService.findOne(id);
            if (Objects.nonNull(q)) {
                questionCache.put(id, q);
            }
        }
        return q;
    }

    private SingleFormAnswer getSingleFormAnswer(String id) {
        SingleFormAnswer q = null;
        if (answerCache.containsKey(id)) {
            q = answerCache.get(id);
        } else {
            q = singleFormAnswerService.findOne(id);
            if (Objects.nonNull(q)) {
                answerCache.put(id, q);
            }
        }
        return q;
    }

    private List<SingleFormAnswer> getAnswers(String questionId) {
        if (answersCache.containsKey(questionId)) {
            return answersCache.get(questionId);
        }
        List<SingleFormAnswer> ans = singleFormAnswerService.findBySingleFormQuestionId(questionId);
        if (Objects.isNull(ans)) {
            return new ArrayList<>();
        }
        answersCache.put(questionId, ans);
        return ans;
    }

    /**
     * 用户是否答对
     *
     * @param answers
     * @param userAns
     * @param q
     * @return
     */
    private boolean right(List<SingleFormAnswer> answers, List<String> userAns,
                          SingleFormQuestion q) {
        if (CollectionUtils.isEmpty(answers) || CollectionUtils.isEmpty(userAns) || Objects.isNull(q)) {
            return false;
        }
        switch (q.getType()) {
            case "single-choice":
                for (SingleFormAnswer a : answers) {
                    if (Boolean.TRUE.equals(a.isAnswer()) && a.getId().equals(userAns.get(0))) {
                        return true;
                    }
                }
                return false;
            case "multiple-choice":
                int answerCount = 0;
                int rightAnswerCount = 0;
                for (SingleFormAnswer a : answers) {
                    boolean in = false;
                    for (String id : userAns) {
                        if (id.equals(a.getId())) {
                            in = true;
                            break;
                        }
                    }
                    if (Boolean.TRUE.equals(a.isAnswer())) {
                        rightAnswerCount++;
                        if (in) {
                            answerCount++;
                        } else {
                            return false;
                        }

                    } else {
                        if (in) {
                            return false;
                        }
                    }
                }
                if (answerCount == rightAnswerCount) {
                    return true;
                } else {
                    return false;
                }
            default:
                break;
        }
        return false;
    }

    private void setUserFormExcelTitle(SXSSFWorkbook workbook, SXSSFSheet sheet, FormTaskConfig form) {
        SXSSFRow row = sheet.createRow(0);
        //设置列宽，setColumnWidth的第二个参数要乘以256，这个参数的单位是1/256个字符宽度
        sheet.setColumnWidth(0, 10 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(2, 30 * 256);
        sheet.setColumnWidth(3, 20 * 256);
        sheet.setColumnWidth(4, 20 * 256);
        sheet.setColumnWidth(5, 10 * 256);
        sheet.setColumnWidth(6, 20 * 256);
        sheet.setColumnWidth(7, 20 * 256);//创建时间
        sheet.setColumnWidth(8, 10 * 256);//数量列
        sheet.setColumnWidth(9, 65 * 256);//内容列
        sheet.setColumnWidth(10, 65 * 256);//内容列
        sheet.setColumnWidth(11, 65 * 256);//内容列
        sheet.setColumnWidth(12, 65 * 256);//内容列
        sheet.setColumnWidth(13, 65 * 256);//内容列
        sheet.setColumnWidth(14, 65 * 256);//内容列
        sheet.setColumnWidth(15, 65 * 256);//内容列

        //设置为居中加粗
        SXSSFCell cell;
        cell = row.createCell(0);
        cell.setCellValue("贡献值");
//        cell.setCellStyle(style);
        ahttps:
//qiniu-cdn.gqgood.com/img5fdd5f101e4d437b961c39cf0a834ca6
        cell = row.createCell(1);
        cell.setCellValue("AppId");
//        cell.setCellStyle(style);
        cell = row.createCell(2);
        cell.setCellValue("openId");
//        cell.setCellStyle(style);
        cell = row.createCell(3);
        cell.setCellValue("大学名");
//        cell.setCellStyle(style);
        cell = row.createCell(4);
        cell.setCellValue("电话");
//        cell.setCellStyle(style);
        cell = row.createCell(5);
        cell.setCellValue("状态");
//        cell.setCellStyle(style);
        cell = row.createCell(6);
        cell.setCellValue("名字");
        cell = row.createCell(7);
        cell.setCellValue("创建时间");
//        cell.setCellStyle(style);


        int cellNumer = 8;
        for (SingleFormQuestion q : form.getQuestions()) {
            switch (q.getType()) {
                case "single-choice":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "multiple-choice":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "text-box":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("文本数量");
                    //内容
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "file-upload":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("文件数量");
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "image-upload":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("图片数量");
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "video-upload":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("视频数量");
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "number-box":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("数字选择数量");
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                case "date-box":
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue("日期选择数量");
                    cell = row.createCell(cellNumer++);
                    cell.setCellValue(q.getTitle());
                    break;
                default:
                    break;
            }
        }

    }

    private Integer setChoiceCell(SingleFormQuestion q, SXSSFRow row,
                                  Integer cellNumer, UserFormTaskDetailInfo u) {

        List<SingleFormAnswer> answers = this.getAnswers(q.getId());
        row.createCell(cellNumer++).setCellValue(q.getTitle());
        List<String> uAnsIds = new ArrayList<>();
        for (UserSubmitSingleForm u1 : u.getDatas()) {
            if (StringUtils.isNotBlank(u1.getSingleFormAnswerId())) {
                uAnsIds.add(u1.getSingleFormAnswerId());
            }
        }
        boolean right = this.right(answers, uAnsIds, q);
        if (right) {
            row.createCell(cellNumer++).setCellValue("正确");
        } else {
            row.createCell(cellNumer++).setCellValue("错误");
        }
        return cellNumer;
    }

}
